package de.tub.bazinga.object.particle;

import java.util.Random;

import processing.core.PVector;
import de.tub.bazinga.object.Color;

public class DirectedParticleBehavior implements ParticleBehavior {

	private final Random random;

	private final int minVelocity;
	private final int maxVelocity;
	private final int minLifeTime;
	private final int maxLifeTime;
	private final float maxAccleration;

	private PVector targetPosition = null;

	public DirectedParticleBehavior(int minVel, int maxVel, int minLifeTime,
			int maxLifeTime, float maxAccleration, PVector targetPosition) {
		random = new Random();

		minVelocity = minVel;
		maxVelocity = maxVel;
		this.minLifeTime = minLifeTime;
		this.maxLifeTime = maxLifeTime;
		this.maxAccleration = maxAccleration;
		this.targetPosition = targetPosition;
	}

	public void updateTargetPosition(PVector targetPosition) {
		this.targetPosition = targetPosition;
	}

	@Override
	public PVector getStartVelocity() {
		float velocity = random.nextFloat() * (maxVelocity - minVelocity)
				+ minVelocity;
		float angle = randomAngle();

		float xVel = (float) (velocity * Math.cos(angle));
		float yVel = (float) (velocity * Math.sin(angle));
		return new PVector(xVel, yVel);
	}

	@Override
	public PVector getAccleration(PVector position) {
		if (targetPosition == null) {
			return new PVector(0, 0);
		}

		PVector direction = PVector.sub(targetPosition, position);
		direction.normalize();

		return PVector.mult(direction, maxAccleration);
	}

	@Override
	public int getLifeTime() {
		return random.nextInt(maxLifeTime - minLifeTime) + minLifeTime;
	}

	private float randomAngle() {
		return random.nextFloat() * 360;
	}

	@Override
	public PVector getVelocity(PVector currentVelocity, PVector accleration) {
		PVector newVelocity = PVector.add(currentVelocity, accleration);
		if (Math.sqrt(newVelocity.dot(newVelocity)) > maxVelocity) {
			newVelocity.normalize();
			newVelocity = PVector.mult(newVelocity, maxVelocity);
		} else if (Math.sqrt(newVelocity.dot(newVelocity)) < minVelocity) {
			newVelocity.normalize();
			newVelocity = PVector.mult(newVelocity, minVelocity);
		}

		return newVelocity;
	}

	@Override
	public Color getColor() {
		return new Color(random.nextInt(255), random.nextInt(255),
				random.nextInt(255), 255);
	}

}
